﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using SimpleServiceBus.EndpointManagement.Server.Utilities;
using SimpleServiceBus.Messages.Management.Monitoring;
using SimpleServiceBus.Tests.Stubs;
using SimpleServiceBus.Utilities.Email;

namespace SimpleServiceBus.Tests.Server
{
    [TestFixture]
    public class ExceptionNotificationGovernerTestFixture
    {
        [Test]
        public void GovernerWillForceAggregationAtMaxDelay()
        {
            //Given
            TestEmailService emailService = new TestEmailService();

            var governer = new ExceptionNotificationGoverner
                               {
                                   EmailAggregationDelay = TimeSpan.FromMilliseconds(100),
                                   EmailAggregationMaxDelay = TimeSpan.FromMilliseconds(200)
                               };

            int count = 0;
            Stopwatch timer = new Stopwatch();
            timer.Start();
            while (timer.ElapsedMilliseconds < 500)
            {
                string to = count%2 == 0 ? "Thing1" : "Thing2";
                var notification = new EndpointErrorNotification
                                       {
                                           EndpointID = "ep_" + to,
                                           ErrorMessage = "Error " + count,
                                           FailedMessageID = "message_" + count,
                                           StatusTime = DateTime.Now
                                       };

                //To test thread safety,we'll ensure each error is coming in on a different thread
                Action del = () => governer.SubmitErrorNotification(to, notification, emailService);
                del.BeginInvoke(null, null);

                count++;
            }
            timer.Stop();
            Thread.Sleep(500);
            Assert.That(emailService.SentEmail.Count, Is.GreaterThan(2));
    
        }

        [Test]
        public void GovernerWillAggregateWhenDelayExceeded()
        {
            //Given
            TestEmailService emailService = new TestEmailService();

            var governer = new ExceptionNotificationGoverner
            {
                EmailAggregationDelay = TimeSpan.FromMilliseconds(100),
                EmailAggregationMaxDelay = TimeSpan.FromMilliseconds(1000)
            };

            int count = 0;
            Stopwatch timer = new Stopwatch();
            timer.Start();
            while (timer.ElapsedMilliseconds < 500)
            {
                string to = count % 2 == 0 ? "Thing1" : "Thing2";
                var notification = new EndpointErrorNotification
                {
                    EndpointID = "ep_" + to,
                    ErrorMessage = "Error " + count,
                    FailedMessageID = "message_" + count,
                    StatusTime = DateTime.Now
                };

                //To test thread safety,we'll ensure each error is coming in on a different thread
                Action del = () => governer.SubmitErrorNotification(to, notification, emailService);
                del.BeginInvoke(null, null);

                count++;
                Thread.Sleep(110);
            }
            timer.Stop();
            Thread.Sleep(500);
            Assert.That(emailService.SentEmail.Count, Is.EqualTo(count));

        }
    }
}
